<script setup lang="ts">
import { useRoute } from 'vue-router'
import { onMounted } from 'vue'
import { defaultElementTypeProvider, hiprint } from 'vue-plugin-hiprint'
import $ from 'jquery'
import { ElMessage } from 'element-plus'
import startPreview from '../print_tpl/components/print/preview.vue'

// 组合式函数 hooks
import { usePaper } from '../print_tpl/components/hooks/use-paper'
import { useZoom } from '../print_tpl/components/hooks/use-zoom'

// 工具
import { newHiprintPrintTemplate } from '../print_tpl/components/utils/template-helper'
import apiPrintTpl from '@/api/modules/print_tpl'

const route = useRoute()
// 组合式函数 hooks
const TEMPLATE_KEY = getCurrentInstance()?.type.name // 存储模板对象的 key
const { paperTypes, curPaperType, paperPopVisible, paperWidth, paperHeight, showPaperPop, setPaper, setPaperOther } = usePaper(TEMPLATE_KEY)
const { scaleValue, changeScale } = useZoom(TEMPLATE_KEY)
const pageData = reactive({
  hiprintTemplate: {} as any,
  tmplJson: route.query.tmpl || '{}',
  name: route.query.name,
  id: route.query.id,
})
const previewRef = ref()
/**
 * 旋转纸张
 */
function rotatePaper() {
  pageData.hiprintTemplate.rotatePaper()
}
/**
 * 清空所有元素
 */
function clearPaper() {
  pageData.hiprintTemplate.clear()
}
// 初始化 provider
hiprint.init({
  providers: [defaultElementTypeProvider()],
})
/**
 * 这里必须要在 onMounted 中去构建 左侧可拖拽元素 或者 设计器
 * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
 */
onMounted(() => {
  buildLeftElement()
  buildDesigner()
})
/**
 * 构建左侧可拖拽元素
 * 注意: 可拖拽元素必须在 hiprint.init() 之后调用
 * 而且 必须包含 class="ep-draggable-item" 否则无法拖拽进设计器
 */
function buildLeftElement() {
  hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'))
}
/**
 * 构建设计器
 * 注意: 必须要在 onMounted 中去构建
 * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
 */

function buildDesigner() {
  // // document.getElementById('hiprint-printTemplate')?.innerHTML = ''
  // $('#hiprint-printTemplate').empty() // 先清空, 避免重复构建
  // pageData.hiprintTemplate = new hiprint.PrintTemplate({
  //   settingContainer: '#PrintElementOptionSetting', // 元素参数容器
  // })
  // // 构建 并填充到 容器中
  // // 可以先 console.log($("#hiprint-printTemplate")) 看看是否有该 dom
  // pageData.hiprintTemplate.design('#hiprint-printTemplate')

  $('#hiprint-printTemplate').empty() // 先清空, 避免重复构建
  // 注意事项: 模板json(object)
  // 如果使用 vue ref创建的模板json, 需要使用 .value 获取 (确保内部能够使用 object.key 拿到对应数据就行)
  pageData.hiprintTemplate = newHiprintPrintTemplate(TEMPLATE_KEY, {
    template: JSON.parse(pageData.tmplJson as string), // 模板json(object)
    settingContainer: '#PrintElementOptionSetting', // 元素参数容器
  })
  // 构建 并填充到 容器中
  pageData.hiprintTemplate.design('#hiprint-printTemplate')
}
function printTest() {
  const printData = { table: [{ name: '132123123' }, { name: 'ewrwerwr' }, { name: 'sdfsdfdfd' }] }
  const hiprintTemplate = new hiprint.PrintTemplate({ template: pageData.tmplJson })
  // 打印
  hiprintTemplate.print(printData)
}
function getHtml() {
  const html = pageData.hiprintTemplate.getHtml({})
  previewRef.value.showModal(html)
}
/**
 * 浏览器打印
 */
function print() {
  // 打印数据，key 对应 元素的 字段名
  const printData = { name: 'CcSimple' }
  // 参数: 打印时设置 左偏移量，上偏移量
  const options = { leftOffset: -1, topOffset: -1 }
  // 扩展
  const ext = {
    callback: () => {
      // console.log('浏览器打印窗口已打开')
    },
    styleHandler: () => {
      // 重写 文本 打印样式
      return '<style>.hiprint-printElement-text{color:red !important;}</style>'
    },
  }
  // 调用浏览器打印
  pageData.hiprintTemplate.print(printData, options, ext)
}
/**
 * 直接打印: 借助客户端,静默打印(无弹窗直接打印)
 * 注意: 需要先连接客户端
 */
function print2() {
  if (hiprint.hiwebSocket.opened) {
    pageData.hiprintTemplate.print2({})
  }
  else {
    // alert('请先连接客户端(刷新网页), 然后再点击「直接打印」')
  }
}
/**
 * 导出模板 json
 * 必须确保 hiprintTemplate 已成功创建
 */
function exportJson() {
  const json = pageData.hiprintTemplate.getJson()
  pageData.tmplJson = json
}
/**
 * 导出模板 json tid
 * 仅导出 options, 不导出 printElementType
 * 必须确保 hiprintTemplate 已成功创建
 */
function exportJsonTid() {
  // const json = pageData.hiprintTemplate.getJsonTid()
}
function sumbitTmpl() {
  pageData.tmplJson = JSON.stringify(pageData.hiprintTemplate.getJson())
  apiPrintTpl.createOrUpdate({ id: (pageData.id as any) * 1, name: pageData.name || '打印模板', tmpl: pageData.tmplJson }).then(() => {
    ElMessage.success({
      message: '模板提交成功',
      center: true,
    })
    // router.push({ name: 'print_tpl_list' })
  }).catch((e: any) => {
    if (e.msg) {
      ElMessage.error({
        message: e.msg,
        center: true,
      })
    }
  })
}
</script>

<template>
  <!-- <page-main> -->
  <div class="flex-col">
    <div class="align-center flex-row justify-center" style="margin-top: 10px;margin-bottom: 10px;">
      <button class="secondary circle-10 ml-10" @click.stop="printTest">
        <i class="iconfont sv-preview" />
        打印测试
      </button>
      <button class="secondary circle-10 ml-10" @click.stop="getHtml">
        <i class="iconfont sv-preview" />
        预览
      </button>
      <!-- 纸张大小 A3、A4 等 -->
      <div class="paper">
        <template v-for="(value, type) in paperTypes" :key="type">
          <button :class="curPaperType === type ? 'api' : 'info'" @click="setPaper(type, value)">
            {{ type }}
          </button>
        </template>
        <!-- 自定义纸张 -->
        <button :class="'other' === curPaperType ? 'api' : 'info'" class="auto" @click="showPaperPop">
          自定义纸张
        </button>
        <div class="popover">
          <div v-show="paperPopVisible" class="popover-content flex-col">
            <div style="font-size: 16px; font-weight: bold;">
              设置纸张宽高(mm)
            </div>
            <div class="mt-10 flex-row">
              <input class="input" :value="paperWidth" type="number" placeholder="宽(mm)">
              <span class="ml-10 mr-10">x</span>
              <input class="input" :value="paperHeight" type="number" placeholder="高(mm)">
            </div>
            <button class="primary circle-10" style="margin-top: 6px;" @click.stop="setPaperOther">
              确定
            </button>
          </div>
        </div>
      </div>
      <!-- 缩放 -->
      <div class="align-center ml-10 flex-row">
        <button class="circle-10 info" @click="changeScale(false)">
          <i class="iconfont sv-zoom-out" />
        </button>
        <div style=" width: 40px;margin: 0 4px;">
          {{ (scaleValue * 100).toFixed(0) }}%
        </div>
        <button class="info circle-10" @click="changeScale(true)">
          <i class="iconfont sv-zoom-in" />
        </button>
      </div>
      <button class="circle-10 api ml-10" @click.stop="rotatePaper">
        <i class="iconfont sv-rotate" />
        旋转纸张(宽高互换)
      </button>
      <button class="api circle-10 ml-10" @click.stop="clearPaper">
        <i class="iconfont sv-clear" />
        清空纸张
      </button>
      <button class="api circle-10 ml-10" @click.stop="exportJson">
        <i class="iconfont sv-export" />
        导出模板 json
      </button>
      <button class="api circle-10 ml-10" @click.stop="exportJsonTid">
        导出模板 json tid
        <i class="iconfont sv-export" />
      </button>
      <button class="secondary circle-10 ml-10" @click.stop="print">
        <i class="iconfont sv-printer" />
        浏览器打印
      </button>
      <button class="warning circle-10 ml-10" @click.stop="print2">
        直接打印(需要连接客户端)
        <i class="iconfont sv-printer" />
      </button>
      <button class="warning circle-10 ml-10" @click.stop="sumbitTmpl">
        提交模板
        <i class="iconfont sv-printer" />
      </button>
    </div>
    <div class="flex-row" style="height: 87vh;">
      <div class="flex-2 left">
        <div class="flex-row flex-wrap justify-center">
          <div class="title">
            基础元素
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.text">
            <i class="iconfont sv-text" />
            <span>文本</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.image">
            <i class="iconfont sv-image" />
            <span>图片</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.longText">
            <i class="iconfont sv-longText" />
            <span>长文</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.barcode">
            <i class="iconfont sv-barcode" />
            <span>条码</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.qrcode">
            <i class="iconfont sv-qrcode" />
            <span>二维码</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.table">
            <i class="iconfont sv-table" />
            <span>表格</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.html">
            <i class="iconfont sv-html" />
            <span>html</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.customText">
            <i class="iconfont sv-text" />
            <span>自定义</span>
          </div>
          <div class="title">
            辅助元素
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.hline">
            <i class="iconfont sv-hline" />
            <span>横线</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.vline">
            <i class="iconfont sv-vline" />
            <span>竖线</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.rect">
            <i class="iconfont sv-rect" />
            <span>矩形</span>
          </div>
          <div class="ep-draggable-item item" tid="defaultModule.oval">
            <i class="iconfont sv-oval" />
            <span>圆形</span>
          </div>
        </div>
      </div>
      <div class="flex-5 center">
        <!-- 设计器的 容器 -->
        <div id="hiprint-printTemplate" />
      </div>
      <div class="flex-2 right">
        <!-- 元素参数的 容器 -->
        <div id="PrintElementOptionSetting" />
      </div>
    </div>
    <startPreview ref="previewRef" />
  </div>
  <!-- </page-main> -->
</template>

<style lang="scss" scoped>
/* 重写全局 hiprint 样式 */
.hiprint-headerLine,
.hiprint-footerLine {
  border-color: purple !important;
}

.hiprint-headerLine:hover,
.hiprint-footerLine:hover {
  border-top: 3px dashed purple !important;
}

.hiprint-headerLine:hover::before {
  position: relative;
  top: -14px;
  left: calc(50% - 18px);
  font-size: 12px;
  color: purple;
  content: "页眉线";
  background: #ffff;
}

.hiprint-footerLine:hover::before {
  position: relative;
  top: -14px;
  left: calc(50% - 18px);
  font-size: 12px;
  color: purple;
  content: "页脚线";
  background: #ffff;
}
</style>

<style scoped>
/* 区域 */
.left {
  padding: 10px 0;
  overflow: auto;
  background: white;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 0 rgb(128 0 128 / 20%);
}

.center {
  padding: 20px;
  margin: 0 10px;
  overflow: auto;
  background: white;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 0 rgb(128 0 128 / 20%);
}

.right {
  padding: 10px 0;
  overflow: auto;
  background: white;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 0 rgb(128 0 128 / 20%);
}

/* 左侧拖拽元素样式 */
.title {
  width: 100%;
  margin: 10px 0 0 24px;
  font-size: 16px;
  font-weight: 500;
}

.item {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 38%;
  min-height: 60px;
  padding: 4px 10px;
  margin: 10px 8px 4px;
  background: white;
  border-radius: 4px;
  box-shadow: 2px 2px 2px 2px rgb(171 171 171 / 20%);
}

.item .iconfont {
  font-size: 1.5rem;
}

.item span {
  font-size: 14px;
}

.api {
  background: #00acc1;
}
</style>
